package generalObjects;

import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This class contains a map of each member in the group, represented by a
 * ClientInfo object. It also keeps track of the current Leader of the group,
 * and provides methods to modify these values. For example setLeader(),
 * removeMember(), appendMember().
 */
public class GroupView implements Serializable {

    private static final long serialVersionUID = 7399667224752725589L;

    private ConcurrentHashMap<String, Integer> vClock;
    private ConcurrentHashMap<String, BaseClientContract> gView;
    private String leader;

    public String getLeader() {
        return leader;
    }

    public void setLeader(final String leader) {
        this.leader = leader;
    }

    public GroupView() {
        gView = new ConcurrentHashMap<String, BaseClientContract>();
        vClock = new ConcurrentHashMap<String, Integer>();
    }

    public void appendMember(final String keyName,
            final BaseClientContract member, int seq) {
        gView.put(keyName, member);
        vClock.put(keyName, seq);
    }

    public void removeMember(final String keyName) {
        gView.remove(keyName);
        vClock.remove(keyName);
    }

    public void incrementSeq(String id) {
        int seq = vClock.get(id);
        seq++;
        vClock.put(id, seq);
    }

    public ConcurrentHashMap<String, BaseClientContract> getView() {
        return gView;
    }

    public ConcurrentHashMap<String, Integer> getVectorClock() {
        return vClock;
    }

    public void setView(
            final ConcurrentHashMap<String, BaseClientContract> gView) {
        this.gView = gView;
    }

    public void setVectorClock(final ConcurrentHashMap<String, Integer> vClock) {
        this.vClock = vClock;
    }

    @Override
    public GroupView clone() {
        GroupView view = new GroupView();
        for (final String key : gView.keySet()) {
            final int seq = vClock.get(key);
            final BaseClientContract stub = gView.get(key);
            view.appendMember(key, stub, seq);
        }
        view.setLeader(leader);
        return view;
    }
}
